package com.tpc.control.jpa;

import java.sql.Timestamp;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.tpc.control.util.Formatting;

/**
 * A data access object (DAO) providing persistence and search support for Plant
 * entities. Transaction control of the save(), update() and delete() operations
 * must be handled externally by senders of these methods or must be manually
 * added to each of these methods for data to be persisted to the JPA datastore.
 * 
 * @see com.tpc.control.jpa.Plant
 * @author MyEclipse Persistence Tools
 */

public class PlantDAO implements IPlantDAO {
	// property constants
	public static final String PLANT_NAME = "plantName";
	public static final String ON_LOADING = "onLoading";
	public static final String INPUT_FILE_NAME = "inputFileName";
	public static final String INACT_UPLOAD = "inactUpload";

	private EntityManager getEntityManager() {
		return EntityManagerHelper.getEntityManager();
	}

	/**
	 * Perform an initial save of a previously unsaved Plant entity. All
	 * subsequent persist actions of this entity should use the #update()
	 * method. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#persist(Object)
	 * EntityManager#persist} operation.
	 * 
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * PlantDAO.save(entity);
	 * EntityManagerHelper.commit();
	 * </pre>
	 * 
	 * @param entity
	 *            Plant entity to persist
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void save(Plant entity) {
		EntityManagerHelper.log("saving Plant instance", Level.INFO, null);
		try {
			getEntityManager().persist(entity);
			EntityManagerHelper.log("save successful", Level.INFO, null);
		} catch (RuntimeException re) {
			EntityManagerHelper.log("save failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Delete a persistent Plant entity. This operation must be performed within
	 * the a database transaction context for the entity's data to be
	 * permanently deleted from the persistence store, i.e., database. This
	 * method uses the {@link javax.persistence.EntityManager#remove(Object)
	 * EntityManager#delete} operation.
	 * 
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * PlantDAO.delete(entity);
	 * EntityManagerHelper.commit();
	 * entity = null;
	 * </pre>
	 * 
	 * @param entity
	 *            Plant entity to delete
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void delete(Plant entity) {
		EntityManagerHelper.log("deleting Plant instance", Level.INFO, null);
		try {
			entity = getEntityManager().getReference(Plant.class,
					entity.getPlantId());
			getEntityManager().remove(entity);
			EntityManagerHelper.log("delete successful", Level.INFO, null);
		} catch (RuntimeException re) {
			EntityManagerHelper.log("delete failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Persist a previously saved Plant entity and return it or a copy of it to
	 * the sender. A copy of the Plant entity parameter is returned when the JPA
	 * persistence mechanism has not previously been tracking the updated
	 * entity. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
	 * operation.
	 * 
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * entity = PlantDAO.update(entity);
	 * EntityManagerHelper.commit();
	 * </pre>
	 * 
	 * @param entity
	 *            Plant entity to update
	 * @return Plant the persisted Plant entity instance, may not be the same
	 * @throws RuntimeException
	 *             if the operation fails
	 */
	public Plant update(Plant entity) {
		EntityManagerHelper.log("updating Plant instance", Level.INFO, null);
		try {
			Plant result = getEntityManager().merge(entity);
			EntityManagerHelper.log("update successful", Level.INFO, null);
			return result;
		} catch (RuntimeException re) {
			EntityManagerHelper.log("update failed", Level.SEVERE, re);
			throw re;
		}
	}

	public Plant findById(String id) {
		EntityManagerHelper.log("finding Plant instance with id: " + id,
				Level.INFO, null);
		try {
			Plant instance = getEntityManager().find(Plant.class, id);
			return instance;
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Find all Plant entities with a specific property value.
	 * 
	 * @param propertyName
	 *            the name of the Plant property to query
	 * @param value
	 *            the property value to match
	 * @return List<Plant> found by query
	 */
	@SuppressWarnings("unchecked")
	public List<Plant> findByProperty(String propertyName, final Object value) {
		EntityManagerHelper.log("finding Plant instance with property: "
				+ propertyName + ", value: " + value, Level.INFO, null);
		try {
			final String queryString = "select model from Plant model where model."
					+ propertyName + "= :propertyValue";
			Query query = getEntityManager().createQuery(queryString);
			query.setParameter("propertyValue", value);
			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find by property name failed",
					Level.SEVERE, re);
			throw re;
		}
	}

	public List<Plant> findByPlantName(Object plantName) {
		return findByProperty(PLANT_NAME, plantName);
	}

	public List<Plant> findByOnLoading(Object onLoading) {
		return findByProperty(ON_LOADING, onLoading);
	}

	public List<Plant> findByInputFileName(Object inputFileName) {
		return findByProperty(INPUT_FILE_NAME, inputFileName);
	}

	public List<Plant> findByInactUpload(Object inactUpload) {
		return findByProperty(INACT_UPLOAD, inactUpload);
	}

	/**
	 * Find all Plant entities.
	 * 
	 * @return List<Plant> all Plant entities
	 */
	@SuppressWarnings("unchecked")
	public List<Plant> findAll() {
		EntityManagerHelper
				.log("finding all Plant instances", Level.INFO, null);
		try {
			final String queryString = "select model from Plant model";
			Query query = getEntityManager().createQuery(queryString);
			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find all failed", Level.SEVERE, re);
			throw re;
		}
	}
	
	/* Customize */
	public List<Plant> findByOnLoading(Object plantId1, Object plantId2, Object onLoading) {
		EntityManagerHelper.log("findByQuery1 CommonData instance", Level.INFO, null);
		try {
			System.out.println("plantId: "+plantId1+"::"+plantId2);
			String[] plantId = Formatting.generateFromToText(plantId1, plantId2, 4);
			String queryString = "select model from Plant model where (model.onLoading = :propertyValue1) ";
			if (!((String)plantId1).equals("") || !((String)plantId2).equals("")) {
				queryString += " and (model.plantId " + " between :propertyValue2 "
					+ " and :propertyValue3) ";
			}
			System.out.println("queryString: "+queryString);
			
			Query query = getEntityManager().createQuery(queryString);
			query.setParameter("propertyValue1", onLoading);
			if (!((String)plantId1).equals("") || !((String)plantId2).equals("")) {
				query.setParameter("propertyValue2", plantId[0]);
				query.setParameter("propertyValue3", plantId[1]);
			}
			
			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find by property name failed",
					Level.SEVERE, re);
			throw re;
		}
	}

}